import { debounce } from "@/utils/index.js";
import { drawTypeEnum, dragTypeEnum } from "@/constant/dictionary";
import { cloneDeep } from "lodash";
import {
  polygonHasIntersectingLinesAllowingVertices,
  multipleSegmentsIntersect,
  pointInPolygon,
} from "@/utils/math.js";
// export const drawTypeEnum = object2Enum({
//     0: "lines",
//     1: "polygons",
// });
class DrawBase {
  // 存储id和点信息对应关系
  #_savePointInfoOfId = [];
  #_drawTypeStyle = {
    [drawTypeEnum.lines]: {
      lineWidth: 2,
      maxCount: 2,
      maxPointCount: 2,
      dataTest:
        "[[[25,44],[213,156]],[[110,26],[37,99]],[[204,110],[206,31]],[[166,33],[80,159]],[[25,136],[186,82]]]",
    },
    [drawTypeEnum.polygons]: {
      lineWidth: 1,
      maxCount: 10,
      maxPointCount: 10,
      dataTest:
        "[[[16,5],[5,175],[256,2]],[[29,16],[129,173],[253,177],[253,48]],[[98,55],[31,111],[188,139]]]",
    },
  };
  #_judgeIsIntersect_fnMap = {};
  set _judgeIsIntersect_fnMap(value) {
    this.#_judgeIsIntersect_fnMap[this.drawType] = value;
  }
  constructor(props, params) {
    const { emits } = params || {};
    this.emits = emits;
    this.props = props;
    this.can = null;
    this.ctx = null;
    this.canSave = null;
    this.ctxSave = null;
    this.pointX = null;
    this.pointY = null;
    this.drawEnd = true; // 结束绘制
    this.isReset = false; // 是否重置
    this.pointArr = []; //存放坐标的数组
    this.oldPointArr = []; //克隆拖拽前存放坐标的数组，便于拖拽相关逻辑实现
    this.pointArrSave = []; //保存存放坐标的数组
    this.oIndex = -1; //判断鼠标是否移动到起始点处，-1为否，1为是
    this.ctxFillStyle = "rgba(21, 119, 255, 0.30)"; // 填充颜色
    this.ctxSaveFillStyle = "rgba(21, 119, 255, 0.30)"; // 填充颜色
    this.arcFillStyle = "#1577FF"; // 圆点的填充颜色
    this.highlightLineStyle = ""; // 线段的高亮颜色
    this.highlightPolygonStyle = ""; // 多边形区域的高亮颜色
    this.selectObject = null; // 选择的拖动点在pointArrSave的位置
    this.isDragging = false; // 是否可以拖动
    this.selectMovePoint = null; // 鼠标点在pointArrSave的位置
    this.selectMoveIndex = null; // 鼠标点在pointArrSave的下标
    this.dragType = null; // 鼠标点在图形中的位置点、线、面
    // 保存上一个鼠标位置
    this.prevX, this.prevY;
    this.pointSize = 4;
    this.debugFlag = false;
    this.drawType = drawTypeEnum.polygons; // 是绘制多边形还是绘制线段？默认是绘制多边形
    this.res = {
      [drawTypeEnum.lines]: [],
      [drawTypeEnum.polygons]: [],
    };
    const getCommonState = debounce((fromMsg) => {
      console.log(
        JSON.parse(JSON.stringify(this.pointArr)),
        fromMsg || "this.pointArr"
      );
    }, 200);
  }
  get drawTypeStyle() {
    return this.#_drawTypeStyle;
  }
  get _savePointInfoOfId() {
    return this.#_savePointInfoOfId;
  }
  splice_savePointInfoOfId(...args) {
    return this._savePointInfoOfId.splice(...args);
  }
  operate_savePointInfoOfId(type, ...args) {
    let arrRes;
    switch (type) {
      case "splice":
        arrRes = this.#_savePointInfoOfId.splice(...args);
        break;
      case "pop":
        arrRes = this.#_savePointInfoOfId.pop();
        break;
      case "push":
        arrRes = this.#_savePointInfoOfId.push(...args);
        break;
      default:
        break;
    }
    return arrRes;
  }
  //   组件取消挂载前
  unMountedCb = () => {
    this.can?.removeEventListener("contextmenu", this.onRightClick);
  };
  //   初始化画布的dom
  initDom = (can, canSave) => {
    this.debugFlag && console.log("initDom被调用");
    this.can = can;
    this.canSave = canSave;
  };
  init = (isResize) => {
    this.debugFlag && console.log("init被调用");
    if (!this.can || !this.canSave) {
      return;
    }
    this.ctx = this.can?.getContext("2d");
    this.ctxSave = this.canSave?.getContext("2d");
    this.ctx.strokeStyle = "#1577FF"; //线条颜色
    this.ctx.lineWidth = this.#_drawTypeStyle[this.drawType].lineWidth; //线条粗细
    this.ctxSave.strokeStyle = "#1577FF"; //线条颜色
    this.ctxSave.lineWidth = this.#_drawTypeStyle[this.drawType].lineWidth; //线条粗细
    if (isResize) {
      this.ClickClear();
    }
    this.drawTypeInit();
    this.props.editable ? this.ClickDraw() : this.disabledDraw();
    this.can?.removeEventListener("contextmenu", this.onRightClick);
    this.can?.addEventListener("contextmenu", this.onRightClick);
  };
  drawTypeInit() {}
  // 获取缩放比例
  getZoomRatio = () => {
    this.debugFlag && console.log("getZoomRatio被调用");
    let width = parseInt(this.props.imageWidth || this.props.canvasWidth);
    let height = parseInt(this.props.imageHeight || this.props.canvasHeight);
    return {
      scaleX: this.props.naturalWidth / width,
      scaleY: this.props.naturalHeight / height,
    };
  };
  makearc = (ctxObj, x, y, r, s, e, color) => {
    this.debugFlag && console.log("makearc被调用");
    ctxObj.beginPath();
    ctxObj.fillStyle = color;
    ctxObj.arc(x, y, r, s, e);
    ctxObj.fill();
  };

  // 为数组每个节点生成圆点
  drawMaker = (ctxObj, pointArrList, paramsObj) => {
    const { randomSize = this.pointSize, fillStyle = this.arcFillStyle } =
      paramsObj || {};
    for (let i = 0; i < pointArrList.length; i++) {
      this.makearc(
        ctxObj,
        pointArrList[i].x,
        pointArrList[i].y,
        this.GetRandomNum(
          pointArrList[i].randomSize ?? randomSize,
          pointArrList[i].randomSize ?? randomSize
        ),
        0,
        180,
        fillStyle
      );
    }
  };
  onRightClick = (e) => {
    this.debugFlag && console.log("onRightClick被调用");
    // // 防止打开菜单菜单
    // e.stopPropagation();
    // e.preventDefault();

    // // 如果没有点 不用撤销
    // if (this.pointArr.length === 0) return;
    // this.pointArr.pop(); // 移除最后一个点
    // return false;
  };
  judgeIsIntersect = (pointArrList) => {
    if (
      this.#_judgeIsIntersect_fnMap[this.drawType] &&
      (this.props.judgePointIsIntersect || this.props.judgeIsOverlapping)
    ) {
      // 是否存在交叉项
      return this.#_judgeIsIntersect_fnMap[this.drawType](pointArrList ?? []);
    }
    return false;
  };
  /*canvas生成圆点*/
  GetRandomNum = (Min, Max) => {
    this.debugFlag && console.log("GetRandomNum被调用");
    let Range = Max - Min;
    let Rand = Math.random();
    return Min + Math.round(Rand * Range);
  };
  /*清空选区*/
  ClickClear = () => {
    this.debugFlag && console.log("ClickClear被调用");
    this.ctx.clearRect(0, 0, this.can.width, this.can.height);
    this.ctxSave.clearRect(0, 0, this.canSave.width, this.canSave.height);
    this.pointArr = [];
    this.res[this.drawType] = [];
    this.drawEnd = true;
  };
  /*验证canvas画布是否为空函数*/
  isCanvasBlank = (canvas) => {
    this.debugFlag && console.log("isCanvasBlank被调用");
    let blank = document.createElement("canvas"); //创建一个空canvas对象
    blank.width = canvas.width;
    blank.height = canvas.height;
    return canvas.toDataURL() == blank.toDataURL(); //为空 返回true
  };

  // ---------------------------------------------------------------
  // 存储已生成的点线
  canvasSave = (pointArr) => {
    this.debugFlag && console.log("canvasSave被调用");
    this.ctxSave.clearRect(0, 0, this.ctxSave.width, this.ctxSave.height);
    this.drawMaker(this.ctxSave, pointArr);
    this.ctxSave.beginPath();
    if (pointArr.length > 1) {
      this.ctxSave.moveTo(pointArr[0].x, pointArr[0].y);
      for (let i = 1; i < pointArr.length; i++) {
        this.ctxSave.lineTo(pointArr[i].x, pointArr[i].y);
        this.ctxSave.fillStyle = this.ctxSaveFillStyle; //填充颜色
      }
      this.ctxSave.stroke(); //绘制
      this.ctxSave.closePath();
    }
  };
  // 重新画图
  drawRects = (data) => {
    this.debugFlag && console.log("drawRects被调用");
    if (data) {
      this.isReset = false;
      this.ClickClear();
      data.forEach((item) => {
        ((this.props.pointItemIsObj ? item.positions : item) || []).forEach(
          (item1) => {
            this.pointArr.push({ x: item1[0], y: item1[1] });
          }
        );
        this.canvasSave(this.pointArr); //保存点线同步到另一个canvas
        this.saveCanvas(); //生成画布
      });
    }
  };
  // 拖动重新画图
  dragCircle = (e) => {
    this.debugFlag && console.log("dragCircle被调用");
    // 判断是否可以拖动
    if (this.isDragging == true) {
      let x = e.offsetX ?? e.layerX;
      let y = e.offsetY ?? e.layerY;
      const positionObj = this.getSelectPosition();
      if (
        positionObj.some((item) => {
          return this.judgeInCircle(
            {
              x: item[0],
              y: item[1],
            },
            {
              x,
              y,
            },
            this.props.faultTolerant
          );
        })
      ) {
        // 如果是在端点处，重置掉鼠标点的数组下标值
        this.selectMoveIndex = -1;
        this.dragType = dragTypeEnum.point;
      }
      if (this.dragType === dragTypeEnum.point) {
        // 取得画布上被点击的点
        positionObj[this.selectObject[1]][0] = e.offsetX;
        positionObj[this.selectObject[1]][1] = e.offsetY;
      } else if (this.dragType === dragTypeEnum.line) {
      } else if (this.dragType === dragTypeEnum.face) {
        if (this.prevX && this.prevY) {
          // 计算鼠标移动距离
          const deltaX = e.clientX - this.prevX;
          const deltaY = e.clientY - this.prevY;
          this.getMovePatternPosition().forEach((item, index, arr) => {
            arr[index][0] += deltaX;
            arr[index][1] += deltaY;
          });
        }
        // 保存当前鼠标位置
        this.prevX = e.clientX;
        this.prevY = e.clientY;
      }
      this.drawRects(this.res[this.drawType]);
    }
  };
  // 刷新鼠标点所在数据信息【第几个图形，图形第几个点】0开始计算
  refreshSelectMovePoint = (e) => {
    if (this.res[this.drawType].length > 0) {
      this.selectMovePoint = null;
      this.res[this.drawType].forEach((item, index) => {
        const arrayDemo =
          (this.props.pointItemIsObj ? item.positions : item) || [];
        let x, y;
        if (e.offsetX || e.layerX) {
          x = e.offsetX ?? e.layerX;
          y = e.offsetY ?? e.layerY;
          for (let i = 0; i < arrayDemo.length; i++) {
            if (
              this.judgeInCircle(
                {
                  x: arrayDemo[i][0],
                  y: arrayDemo[i][1],
                },
                {
                  x,
                  y,
                },
                this.props.faultTolerant
              )
            ) {
              this.selectMovePoint = [index, i];
            }
          }
        }
      });
    }
  };
  // 获取鼠标在图形列的下标，为-1则没在图形内
  judgeInPolygonIndex = (e) => {
    this.selectMoveIndex =
      (this.res[this.drawType] || []).findIndex((item) => {
        const arrayDemo =
          (this.props.pointItemIsObj ? item.positions : item) || [];
        return pointInPolygon(e.offsetX, e.offsetY, arrayDemo);
      }) ?? -1;
    if (this.selectMoveIndex > -1) {
      this.dragType = dragTypeEnum.face;
      this.isDragging = true;
      // 保存当前鼠标位置
      this.prevX = e.clientX;
      this.prevY = e.clientY;
    }
    return this.selectMoveIndex;
  };
  // 鼠标附近的点变大
  highlightPoint = (e) => {
    if (this.res[this.drawType].length > 0 && this.selectMovePoint?.length) {
      const pointInfo = this.getMovePointPosition()[this.selectMovePoint[1]];
      pointInfo &&
        this.drawMaker(this.ctx, [
          {
            x: pointInfo[0],
            y: pointInfo[1],
            randomSize: this.pointSize + 2,
          },
        ]);
    }
  };
  // 鼠标附近的线段高亮（未实现
  highlightLine = (e) => {
    // if (this.res[this.drawType].length > 0 && this.selectMovePoint?.length) {
    // }
  };
  // 鼠标所在图像区域高亮
  highlightPolygon = (e) => {
    if (this.res[this.drawType].length > 0 && this.selectMovePoint?.length) {
    }
  };
  getSelectPosition = () => {
    if (this.selectObject?.length !== 2) {
      return [];
    }
    return this.props.pointItemIsObj
      ? this.res[this.drawType][this.selectObject[0]].positions
      : this.res[this.drawType][this.selectObject[0]];
  };
  getMovePointPosition = () => {
    if (!this.selectMovePoint?.length) {
      return [];
    }
    return this.props.pointItemIsObj
      ? this.res[this.drawType][this.selectMovePoint[0]].positions
      : this.res[this.drawType][this.selectMovePoint[0]];
  };
  // 获取鼠标放入的图案的点位数据
  getMovePatternPosition = () => {
    if (this.selectMoveIndex > -1) {
      return this.props.pointItemIsObj
        ? this.res[this.drawType][this.selectMoveIndex].positions
        : this.res[this.drawType][this.selectMoveIndex];
    }
    return [];
  };
  setSelectPosition = (positions) => {
    if (this.props.pointItemIsObj) {
      this.res[this.drawType][this.selectObject[0]].positions = positions;
    } else {
      this.res[this.drawType][this.selectObject[0]] = positions;
    }
  };
  // 遍历元素在哪一个圆上
  circle = (arrData, clientX, clientY, index) => {
    this.debugFlag && console.log("circle被调用");
    for (let i = 0; i < arrData.length; i++) {
      if (
        this.judgeInCircle(
          {
            x: arrData[i][0],
            y: arrData[i][1],
          },
          {
            x: clientX,
            y: clientY,
          },
          this.props.faultTolerant
        )
      ) {
        this.isDragging = true;
        this.selectObject = [index, i];
        const positionObj = this.getSelectPosition();
        this.oldPointArr = cloneDeep(
          positionObj.map((item) => ({ x: item[0], y: item[1] }))
        );
      }
    }
  };
  // 判断点的位置是否在圆心为p1，半径为faultTolerant的圆里面
  judgeInCircle = (p1, p2, faultTolerant) => {
    // Math.abs返回绝对值
    // Math.sqrt返回一个数的平方根
    // Math.pow幂函数运算
    return (
      Math.abs(Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2))) -
        faultTolerant <
      0
    );
  };
  // Canvas点击事件
  // 遍历所有的坐标点
  clickPoint = (e) => {
    this.debugFlag && console.log("clickPoint被调用");
    if (this.res[this.drawType].length > 0) {
      this.judgeInPolygonIndex(e);
      this.res[this.drawType].forEach((item, index) => {
        const arrayDemo =
          (this.props.pointItemIsObj ? item.positions : item) || [];
        this.circle(arrayDemo, e.offsetX, e.offsetY, index);
      });
    }
  };
  // -----------------------------
  // 删除上一个图形
  DeletePrevious = () => {
    this.debugFlag && console.log("DeletePrevious被调用");
    if (this.res[this.drawType].length <= 1) {
      // 清空
      this.ClickReset();
      return;
    }
    this.pointArr.pop();
    this.res[this.drawType].pop();
    this.#_savePointInfoOfId.pop();
    this.canvasSave(this.pointArr); //保存点线同步到另一个canvas
    this.saveCanvas(); //生成画布
    //   重新画图
    this.drawRects(this.res[this.drawType]);
  };
  // 绘制坐标
  ClickDraw = () => {
    this.debugFlag && console.log("ClickDraw被调用");
    if (
      this.res[this.drawType]?.length >=
      this.#_drawTypeStyle[this.drawType].maxCount
    ) {
      return;
    }
    this.drawEnd = false;
    this.isReset = false;
  };
  // 禁用绘制坐标
  disabledDraw = () => {
    this.debugFlag && console.log("disabledDraw被调用");
    this.drawEnd = true;
    this.isReset = true;
  };
  // 绘制线段坐标
  ClickDrawLine = () => {
    this.debugFlag && console.log("ClickDrawLine被调用");
    this.drawEnd = false;
    this.isReset = false;
  };
  // 生成坐标
  ClickSet = () => {
    this.debugFlag && console.log("ClickSet被调用");
    this.isReset = false;
    this.ClickClear();
    let dataTest = this.#_drawTypeStyle[this.drawType].dataTest;
    let RatioInfo = this.getZoomRatio();
    JSON.parse(dataTest).forEach((item) => {
      item.forEach((item1) => {
        this.pointArr.push({
          x: item1[0] / RatioInfo.scaleX,
          y: item1[1] / RatioInfo.scaleY,
        });
      });
      console.log("生成坐标", this.pointArr);
      this.canvasSave(this.pointArr); //保存点线同步到另一个canvas
      this.saveCanvas(); //生成画布
    });
  };
  // 重置坐标
  ClickReset = () => {
    this.debugFlag && console.log("ClickReset被调用");
    this.isReset = true;
    this.ClickClear();
  };
  // 提交坐标
  ClickPut = () => {
    this.debugFlag && console.log("ClickPut被调用");
    let RatioInfo = this.getZoomRatio();
    return (this.res[this.drawType] || []).map((item, idx) => {
      return this.props.pointItemIsObj
        ? {
            ...item,
            ...(this.#_savePointInfoOfId[idx] || null),
            positions: item.positions.map((item) => [
              parseInt(item[0] * RatioInfo.scaleX),
              parseInt(item[1] * RatioInfo.scaleY),
            ]),
          }
        : item.map((item) => [
            parseInt(item[0] * RatioInfo.scaleX),
            parseInt(item[1] * RatioInfo.scaleY),
          ]);
    });
  };
  // --------------------------------------------------
  // 点击画点
  ClickDrawPoint() {}
  // 停止拖动或者点击画点
  stopDragging() {}
  // 鼠标移动
  MouseMove = (e) => {
    this.debugFlag && console.log("MouseMove被调用");
    if (!this.ctx) {
      return;
    }
    this.refreshSelectMovePoint(e);

    this.dragCircle(e);
    if (e.offsetX || e.layerX) {
      this.pointX = e.offsetX ?? e.layerX;
      this.pointY = e.offsetY ?? e.layerY;
      let piX, piY;
      /*清空画布*/
      this.ctx.clearRect(0, 0, this.can.width, this.can.height);
      /*鼠标下跟随的圆点*/
      // 将所有点反馈到操作canvas上，最后封闭时再绘制保存
      this.drawMaker(
        this.ctx,
        this.pointArr.concat({ x: this.pointX, y: this.pointY })
      );
      this.highlightPoint(e);
      this.highlightLine(e);
      this.highlightPolygon(e);

      if (this.pointArr.length > 0) {
        if (
          this.pointX > this.pointArr[0].x - 15 &&
          this.pointX < this.pointArr[0].x + 15 &&
          this.pointY > this.pointArr[0].y - 15 &&
          this.pointY < this.pointArr[0].y + 15
        ) {
          if (this.pointArr.length > 1) {
            piX = this.pointArr[0].x;
            piY = this.pointArr[0].y;
            this.oIndex = 1;
          }
        } else {
          piX = this.pointX;
          piY = this.pointY;
          this.oIndex = -1;
        }
        /*开始绘制*/
        this.ctx.beginPath();
        this.ctx.moveTo(this.pointArr[0].x, this.pointArr[0].y);
        if (this.pointArr.length > 1) {
          for (let i = 1; i < this.pointArr.length; i++) {
            this.ctx.lineTo(this.pointArr[i].x, this.pointArr[i].y);
          }
        }
        this.ctx.lineTo(piX, piY);
        this.ctx.fillStyle = this.ctxFillStyle; //填充颜色
        this.ctx.fill(); //填充
        this.ctx.stroke(); //绘制
      }
    }
  };
  /*生成画布 结束绘画*/
  saveCanvas = (pushToSave = true) => {
    this.debugFlag && console.log("saveCanvas被调用");
    let pointArrSaveTemp = [];
    this.ctx.clearRect(0, 0, this.can.width, this.can.height);
    this.drawEnd = true;
    this.ctxSave.closePath(); //结束路径状态，结束当前路径，如果是一个未封闭的图形，会自动将首尾相连封闭起来
    this.ctxSave.fill(); //填充
    this.ctxSave.stroke(); //绘制
    if (
      this.pointArr.length &&
      this.pointArr[0].x === this.pointArr[this.pointArr.length - 1].x &&
      this.pointArr[0].y === this.pointArr[this.pointArr.length - 1].y
    ) {
      this.pointArr.pop();
    }
    this.pointArr.forEach((item) => {
      pointArrSaveTemp.push([item.x, item.y]);
    });
    if (pointArrSaveTemp.length) {
      const saveInfo = { addFlag: true, positions: pointArrSaveTemp };
      this.res[this.drawType].push(
        this.props.pointItemIsObj ? saveInfo : pointArrSaveTemp
      );
      pushToSave &&
        this.operate_savePointInfoOfId(
          "push",
          this.props.pointItemIsObj ? saveInfo : pointArrSaveTemp
        );
    }
    this.pointArr = [];
    // 限制只能画maxCount个区域
    if (
      this.res[this.drawType].length <
      this.drawTypeStyle[this.drawType].maxCount
    ) {
      this.ClickDraw();
    }
  };
}
export class Polygons extends DrawBase {
  constructor(...args) {
    super(...args);
    this.drawType = drawTypeEnum.polygons;
    this._judgeIsIntersect_fnMap = polygonHasIntersectingLinesAllowingVertices;
  }
  drawTypeInit() {
    this.props.polygons?.length && this.drawPolygons(this.props.polygons);
  }
  // rectPointList: [[x1, y1], [x2, y2], [x3, y3], [x4, y4]]
  judgeIsFullScreen = (rectPointList) => {
    if (!rectPointList || rectPointList.length !== 4) {
      return false;
    }
    const flag = rectPointList.every((item, idx) => {
      let resFlag = false;
      switch (idx) {
        case 0:
          if (Array.isArray(item)) {
            resFlag = item[0] === 0 && item[1] === 0;
          }
          break;
        case 1:
          if (Array.isArray(item)) {
            resFlag =
              parseInt(item[0]) ===
                parseInt(this.props.imageWidth || this.props.canvasWidth) &&
              item[1] === 0;
          }
          break;
        case 2:
          if (Array.isArray(item)) {
            resFlag =
              parseInt(item[0]) ===
                parseInt(this.props.imageWidth || this.props.canvasWidth) &&
              parseInt(item[1]) ===
                parseInt(this.props.imageHeight || this.props.canvasHeight);
          }
          break;
        case 3:
          if (Array.isArray(item)) {
            resFlag =
              item[0] === 0 &&
              parseInt(item[1]) ===
                parseInt(this.props.imageHeight || this.props.canvasHeight);
          }
          break;
        default:
          break;
      }
      return resFlag;
    });
    return flag;
  };
  drawPolygons = (arr) => {
    this.debugFlag && console.log("drawPolygons被调用");
    this.drawEnd = true;
    let RatioInfo = this.getZoomRatio();
    (arr || []).forEach((pointListObj) => {
      this.operate_savePointInfoOfId("push", pointListObj);
      (
        (this.props.pointItemIsObj ? pointListObj.positions : pointListObj) ||
        []
      ).forEach((item) => {
        this.pointArr.push({
          x: item[0] / RatioInfo.scaleX,
          y: item[1] / RatioInfo.scaleY,
        });
      });
      this.canvasSave(this.pointArr); //保存点线同步到另一个canvas
      this.saveCanvas(false); //生成画布
    });
  };
  // 绘制全屏
  drawFullScreen = () => {
    this.debugFlag && console.log("drawFullScreen被调用");
    if (
      this.res[this.drawType].length >=
      this.drawTypeStyle[this.drawType].maxCount
    ) {
      return;
    }
    this.drawEnd = true;
    let RatioInfo = this.getZoomRatio();
    [
      [0, 0],
      [this.props.imageWidth || this.props.canvasWidth, 0],
      [
        this.props.imageWidth || this.props.canvasWidth,
        this.props.imageHeight || this.props.canvasHeight,
      ],
      [0, this.props.imageHeight || this.props.canvasHeight],
    ].forEach((item) => {
      this.pointArr.push({
        x: item[0] / RatioInfo.scaleX,
        y: item[1] / RatioInfo.scaleY,
      });
      this.pointArrSave.push({
        x: item[0] / RatioInfo.scaleX,
        y: item[1] / RatioInfo.scaleY,
      });
    });
    console.log(cloneDeep(this.pointArr), "this.pointArr");
    this.canvasSave(this.pointArr); //保存点线同步到另一个canvas
    this.saveCanvas(); //生成画布
  };
  // 删除设置的全屏类型的多边形
  deleteFullScreen = () => {
    this.debugFlag && console.log("deleteFullScreen被调用");
    const findIdxList = [];
    (this.res[this.drawType] ?? []).forEach((item, index) => {
      if (
        this.judgeIsFullScreen(
          this.props.pointItemIsObj ? item.positions : item
        )
      ) {
        findIdxList.push(index);
      }
    });
    let idx = -1;
    for (let index = findIdxList.length; index > 0; index--) {
      idx = findIdxList[index];
      this.res[this.drawType].splice(idx, 1);
      this.operate_savePointInfoOfId("splice", idx, 1);
    }
    //   重新画图
    this.drawRects(this.res[this.drawType]);
  };
  // 停止拖动或者点击画点
  stopDragging = (e) => {
    this.debugFlag && console.log("stopDragging被调用");
    if (this.isDragging) {
      this.isDragging = false;
      this.selectMoveIndex = -1;
      if ((this.dragType = dragTypeEnum.point)) {
        const positionObj = this.getSelectPosition();
        const newPositions = this.selectObject?.length
          ? positionObj
              .slice(this.selectObject[1])
              .concat(positionObj.slice(0, this.selectObject[1]))
          : [];
        if (
          this.selectObject?.length &&
          this.judgeIsIntersect(
            newPositions.map((item) => ({ x: item[0], y: item[1] }))
          )
        ) {
          // 判断到重叠后恢复到上次绘制位置
          // 取得画布上被点击的点
          positionObj[this.selectObject[1]][0] =
            this.oldPointArr[this.selectObject[1]].x;
          positionObj[this.selectObject[1]][1] =
            this.oldPointArr[this.selectObject[1]].y;
          this.drawRects(this.res[this.drawType]);
          this.emits("pointIsIntersect");
        }
      }
    } else {
      this.ClickDrawPoint(e);
    }
  };
  // --------------------------------------------------
  // 点击画点
  ClickDrawPoint = (e) => {
    this.debugFlag && console.log("ClickDrawPoint被调用");
    if (!this.drawEnd && !this.isDragging) {
      if (e.offsetX || e.layerX) {
        this.pointX = e.offsetX ?? e.layerX;
        this.pointY = e.offsetY ?? e.layerY;
        let piX, piY;
        if (this.oIndex > 0 && this.pointArr.length > 0) {
          // 绘制结束了
          piX = this.pointArr[0].x;
          piY = this.pointArr[0].y;
          if (this.judgeIsIntersect(this.pointArr)) {
            this.emits("pointIsIntersect");
            /*清空画布*/
            this.pointArr = [];
          } else {
            //画点
            this.drawMaker(this.ctx, [this.pointArr[0]], {
              randomSize: this.pointSize - 2,
            });
            this.pointArr.length <
              this.drawTypeStyle[this.drawType].maxPointCount &&
              this.pointArr.push({ x: piX, y: piY });
            this.canvasSave(this.pointArr); //保存点线同步到另一个canvas
            this.saveCanvas(); //生成画布
          }
        } else {
          // 新增绘制点
          piX = this.pointX;
          piY = this.pointY;
          const pointInfo = { x: piX, y: piY };
          this.drawMaker(this.ctx, [pointInfo], {
            randomSize: this.pointSize - 2,
          });
          this.pointArr.length <
            this.drawTypeStyle[this.drawType].maxPointCount &&
            this.pointArr.push(pointInfo);
        }
      }
    }
  };
}
export class Lines extends DrawBase {
  constructor(...args) {
    super(...args);
    this.drawType = drawTypeEnum.lines;
    this._judgeIsIntersect_fnMap = multipleSegmentsIntersect;
  }
  // 停止拖动或者点击画点
  stopDragging = (e) => {
    this.debugFlag && console.log("stopDragging被调用");
    if (this.isDragging) {
      this.isDragging = false;
      const judgeArr = this.res[this.drawType].map((item) => {
        let itemPointArr = this.props.pointItemIsObj ? item.positions : item;
        return {
          start: {
            x: itemPointArr[0][0],
            y: itemPointArr[0][1],
          },
          end: {
            x: itemPointArr[1][0],
            y: itemPointArr[1][1],
          },
        };
      });
      if (this.selectObject?.length && this.judgeIsIntersect(judgeArr)) {
        // 判断到重叠后恢复到上次绘制位置
        const positionObj = this.getSelectPosition();
        // 取得画布上被点击的点
        positionObj[this.selectObject[1]][0] =
          this.oldPointArr[this.selectObject[1]].x;
        positionObj[this.selectObject[1]][1] =
          this.oldPointArr[this.selectObject[1]].y;
        this.drawRects(this.res[this.drawType]);
        this.emits("pointIsIntersect");
      }
    } else {
      this.ClickDrawPoint(e);
    }
  };
  /*生成画布 结束绘画*/
  saveCanvas = (pushToSave = true) => {
    this.debugFlag && console.log("saveCanvas被调用");
    let pointArrSaveTemp = [];
    this.ctx.clearRect(0, 0, this.can.width, this.can.height);
    this.drawEnd = true;
    this.ctxSave.fill(); //填充
    this.ctxSave.stroke(); //绘制
    this.pointArr.forEach((item) => {
      pointArrSaveTemp.push([item.x, item.y]);
    });
    if (pointArrSaveTemp.length) {
      const saveInfo = { addFlag: true, positions: pointArrSaveTemp };
      this.res[this.drawType].push(
        this.props.pointItemIsObj ? saveInfo : pointArrSaveTemp
      );
      pushToSave &&
        this.operate_savePointInfoOfId(
          "push",
          this.props.pointItemIsObj ? saveInfo : pointArrSaveTemp
        );
    }
    this.pointArr = [];
    // 限制只能画maxCount个区域
    if (
      this.res[this.drawType].length <
      this.drawTypeStyle[this.drawType].maxCount
    ) {
      this.ClickDraw();
    }
  };
  drawTypeInit() {
    this.props.lines?.length && this.drawLines(this.props.lines);
  }
  drawLines = (arr) => {
    this.debugFlag && console.log("drawLines被调用");
    this.drawEnd = true;
    let RatioInfo = this.getZoomRatio();
    (arr || []).forEach((pointListObj) => {
      this.operate_savePointInfoOfId("push", pointListObj);
      (
        (this.props.pointItemIsObj ? pointListObj.positions : pointListObj) ||
        []
      ).forEach((item) => {
        this.pointArr.push({
          x: item[0] / RatioInfo.scaleX,
          y: item[1] / RatioInfo.scaleY,
        });
      });
      this.canvasSave(this.pointArr); //保存点线同步到另一个canvas
      this.saveCanvas(false); //生成画布
    });
  };
  // --------------------------------------------------
  // 点击画点
  ClickDrawPoint = (e) => {
    this.debugFlag && console.log("ClickDrawPoint被调用");
    if (!this.drawEnd && !this.isDragging) {
      if (e.offsetX || e.layerX) {
        this.pointX = e.offsetX ?? e.layerX;
        this.pointY = e.offsetY ?? e.layerY;
        let piX, piY;
        piX = this.pointX;
        piY = this.pointY;
        const pointObj = { x: piX, y: piY };
        const judgeArr = this.res[this.drawType].map((item) => {
          let itemPointArr = this.props.pointItemIsObj ? item.positions : item;
          return {
            start: {
              x: itemPointArr[0][0],
              y: itemPointArr[0][1],
            },
            end: {
              x: itemPointArr[1][0],
              y: itemPointArr[1][1],
            },
          };
        });
        const itemPointArr = this.pointArr.concat([pointObj]);
        itemPointArr.length > 1 &&
          judgeArr.push({
            start: itemPointArr[0],
            end: itemPointArr[1],
          });
        if (this.judgeIsIntersect(judgeArr)) {
          this.emits("pointIsIntersect");
          /*清空画布*/
          this.pointArr = [];
        } else {
          this.drawMaker(this.ctx, [pointObj], {
            randomSize: this.pointSize - 2,
          });
          this.pointArr.push(pointObj);
          // 取消保存，否则线段交叉后无法清除
          // canvasSave(this.pointArr); //保存点线同步到另一个canvas
          if (this.pointArr.length === 2) {
            this.canvasSave(this.pointArr); //保存
            this.saveCanvas(); //生成画布
          }
        }
      }
    }
  };
  // ---------------------------------------------------------------
  // 存储已生成的点线
  canvasSave = (pointArr) => {
    this.debugFlag && console.log("canvasSave被调用");
    this.ctxSave.clearRect(0, 0, this.ctxSave.width, this.ctxSave.height);
    this.drawMaker(this.ctxSave, pointArr);
    this.ctxSave.beginPath();
    if (pointArr.length > 1) {
      this.ctxSave.moveTo(pointArr[0].x, pointArr[0].y);
      for (let i = 1; i < pointArr.length; i++) {
        this.ctxSave.lineTo(pointArr[i].x, pointArr[i].y);
        this.ctxSave.fillStyle = this.ctxSaveFillStyle; //填充颜色
        this.ctxSave.fill();
        this.ctxSave.stroke(); //绘制
      }
    }
  };
}
